<?php

namespace Rexzy\App;

class Model {
    protected $_table;
    protected $_db;
    protected $_lastError;


    public function __construct( $table = '' ) {
        $this->_db = \Rexzy\App\Db::getInstance()->db();
        if ( !$this->_table ) {
            $this->_table = \Rexzy::tb( $table );
        } else {
            $this->_table = \Rexzy::tb( $this->_table );
        }
    }
    
    /**
     * 数据库 SELECT 函数（返回一行查询结果）
     * 
     * @param string $filed 查询要返回的列
     * @param array/string $where 查询条件
     * @param array $binParams 预编译的参数
     * @param int $limit 限制查询的结果的行数
     * @return array 获取的查询的第一行结果
     */
    public function select( $filed, $where = array(), $limit = '', $binParams = array() ) {
        $sql = "SELECT $filed FROM $this->_table ";
        
        if ( $where ) {
            if ( is_array( $where ) ) {
                $where_str = array();
                foreach ( $where as $key => $value ) {
                    $where_str[] = $key . "= " . $this->_db->quote( $value );
                }
                $sql .= ' WHERE ' . implode( ' AND ', $where_str ); 
                
            } else if ( is_string( $where ) ) {
                $sql .= $where; 
            }
        }
       
        if ( $limit ) {
            $sql .= " LIMIIT " . $this->_db->quote( $limit );
        }
        
        $result = $this->_db->prepare( $sql );
        $result->execute( $binParams );
        $data = $result->fetch( \PDO::FETCH_ASSOC );
        $this->_lastError = $result->errorInfo();
        if( $this->_lastError[1] ) {
            return false;
        }
        return $data ?: array();
    }
    
    /**
     * 数据库 SELECT 函数（返回多行查询结果）
     * 
     * @param string $filed 查询要返回的列
     * @param array/string $where 查询条件
     * @param array $binParams 预编译的参数
     * @param int $limit 限制查询的结果的行数
     * @return array 获取的查询的第一行结果
     */
    public function selectAll( $filed, $where = array(), $limit = '', $binParams = array() ) {
        $sql = "SELECT $filed FROM $this->_table ";
       
        if ( $where ) {
            if ( is_array( $where ) ) {
                $where_str = array();
                foreach ( $where as $key => $value ) {
                    $where_str[] = $key . "= " . $this->_db->quote( $value );
                }
                $sql .= ' WHERE ' . implode( ' AND ', $where_str ); 
                
            } else if ( is_string( $where ) ) {
                $sql .= $where; 
            }
        }
        
        if ( $limit ) {
            $sql .= " LIMIT " . $limit;
        }
        
        $result = $this->_db->prepare( $sql );
        $result->execute( $binParams );
        $data = $result->fetchAll( \PDO::FETCH_ASSOC );
        $this->_lastError = $result->errorInfo();
        if( $this->_lastError[1] ) {
            return false;
        }
        return $data ?: array();
    }
    
    /**
     * 数据库 INSERT 函数
     * 
     * @param array $data 需要插入的数据
     * @return string 返回上次插入操作，主键列类型是自增的最后的自增ID
     */
    public function insert( $data = array(), $binParams = array() ) {
        $sql = "INSERT INTO $this->_table ( ";
        $columnName = array_keys( $data );
        $sql .= implode( ', ', $columnName ) . ") VALUES (";
       
        $data_value = array();
        foreach ( $data as $key => $value ) {
            $data_value[] = $this->_db->quote( $value );
        }
        $sql .= implode( ', ', $data_value );
        $sql .= " )";
        
        $this->_db->exec( $sql );
        return $this->_db->lastInsertId();
    }
    
    /** 
     *  数据库 DELETE 函数
     * 
     * @param array $where 筛选条件的数据
     * @return int 返回响应了操作的行数
     */
    public function delete( $where, $binParams = array() ) {
        $sql = "DELETE FROM $this->_table";
        
        if ( $where ) {
            if ( is_array( $where ) ) {
                $where_str = array();
                foreach ( $where as $key => $value ) {
                    $where_str[] = $key . " = " . $this->_db->quote( $value );
               }
                $sql .= " WHERE " . implode( " AND ", $where_str);
            } else if ( is_string( $where ) ) {
                $sql .= " where $where";
            }
        }
        
        $result = $this->_db->prepare( $sql );
        $result->execute( $binParams );
        return $result->rowCount();
    }
    
    /**
     * 数据库 UPDATE 函数
     * 
     * @param array $value 更新的数据
     * @param array/string $where 帅选条件的数据
     * @return int 返回响应操作的行数
     */
    public function update( $values, $where, $binParams = array() ) {
        $sql = "UPDATE $this->_table SET ";
        $new_value = array();
        foreach( $values as $key => $value ) {
            $new_value[] = $key . " = " . $this->_db->quote( $value );
        }
        $sql .= implode( ', ', $new_value );
        
        if ( $where ) {
            if ( is_array( $where ) ) {
                $where_str = array();
                foreach ( $where as $key => $value ) {
                    $where_str[] = $key . "= " . $this->_db->quote( $value );
                }
                $sql .= " where " . implode( 'AND ', $where_str );
            } else if ( is_string( $where ) ) {
                $sql .= " where $where";
            }
        }
        
        $result = $this->_db->prepare( $sql );
        $result->execute( $binParams );
        return $result->rowCount();
    }
    
    /**
     * 通用数据查询
     * 
     * @param string $sql 查询 $sql 与语句
     * @param arrgy $binParams 编译参数
     * @return mixed 查询错误时返回false，成功侧返回查询结果
     */
    public function query( $sql, $binParams = array() ) {
        $result = $this->_db->prepare( $sql );
        $result->execute( $binParams );
        
        $data = $result->fetchAll( \PDO::FETCH_ASSOC );
        $this->_lastError = $result->errorInfo();
        if( $this->_lastError[1] ) {
            return false;
        }
        return $data ?: array();
        
    }
    
    /**
     * 查询编译过程中的错误
     * 
     * @return string 返回编译过程中的错误
     */
    public function error() {
        return $this->_lastError;
    }
}
